/*
  Only compile for golang v1.19+
*/

package main

import (
  "fmt"
  "net/http"
  "github.com/labstack/echo/v4"
  "github.com/labstack/echo/v4/middleware"
  "path/filepath"
  "os"
  "golang.org/x/exp/slog"
  "log"
  "flag"
  "io/ioutil"
  "gopkg.in/yaml.v2"
)


type ST_Config struct {
  RoutineDelayms int `yaml:"routinedelayms"`
  Mysql ST_MysqlConfig `yaml:"mysql"`
}

var (
  GlobalConfig *ST_Config
  flagconf string
)

func load_config_file(f string) *ST_Config {
  dat,err := ioutil.ReadFile(f)
  if err != nil {
    log.Println(err.Error())
    return nil
  }

  var cfg ST_Config
  err = yaml.Unmarshal(dat, &cfg)
  if err != nil {
    log.Println(err.Error())
    return nil
  }
  log.Println(cfg)
  return &cfg
}

func handler_healthy(c echo.Context) error {
    MyLog.Info("ok")
    return c.String(http.StatusOK, "ok")
}

func Handler_Dummy_Data(c echo.Context) error {
    dummy:= c.FormValue("dummy")
    dummy=dummy
    //log.Println(dummy)
    var reply string = ""
    for idx:=0; idx < 5000; idx++ {
      reply=reply+"resp..."
    }
    MyLog.Info(reply)
    return c.String(http.StatusOK, reply)
}

/*
curl -XPOST http://172.24.20.69:30800/api/v1/demo0/ -H 'Content-Type: application/json' -d '{"val": 123, "info": "echo server api, demo0"}'
curl -XPOST http://172.24.20.69:30800/api/v1/demo1 -H 'Content-Type: application/json' -d '{"val": 456, "info": "echo server api, demo1"}'
*/
func Handler_demo(c echo.Context) error {
    type (
      RequestParameter struct {
        Val int `json:"val"`
        Info string `json:"info"`
      }
    )
    ReqPara := new(RequestParameter)
    if err := c.Bind(ReqPara); err != nil {
      return echo.NewHTTPError(http.StatusBadRequest, err.Error())
    }
    //log.Println(ReqPara)
    requestContext := fmt.Sprintf("Your request Context-> IsTLS: %v, Scheme: %s, RealIP: %s, Path: %s\n", 
                                    c.IsTLS(), c.Scheme(), c.RealIP(), c.Path() )
    reply := fmt.Sprintf("Your request parameters-> val: [%d], info: '%s'\n", ReqPara.Val, ReqPara.Info )
    MyLog.Info(reply)
    return c.String(200, requestContext + reply)
}

var MyLog *slog.Logger
func init() {
    flag.StringVar(&flagconf, "conf", "/app/config.yaml", "config path, eg: -conf /app/config.yaml")

    jsonHandler := slog.NewJSONHandler(os.Stdout) //    
    MyLog = slog.New(jsonHandler)  

    // message Channel
    MyChannel = make(chan *ST_MyCh, 10)
    go func() {
      Application_Dispatcher()
    }()
}

func main() {
  
    flag.Parse()
    GlobalConfig = load_config_file(flagconf)

    e := echo.New()

    exe_dir,_ := filepath.Abs(filepath.Dir(os.Args[0]))
    assets_dir:=exe_dir+"/"+"assets"
    MyLog.Info(fmt.Sprintf("Web assets directory %s", assets_dir))
    e.Static("/", exe_dir+"/"+"assets")
  
    // Middleware
    //e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // routes
    e.GET("/api/v1/healthy", handler_healthy)
    e.POST("/api/v1/dummy", Handler_Dummy_Data)
    // API samples
    e.POST("/api/v1/demo0/", Handler_demo)
    e.POST("/api/v1/demo1", Handler_demo)
    e.POST("/api/v1/dbctab", Handler_CreateTable)
    e.POST("/api/v1/dbitab", Handler_InsertTable)
    e.POST("/api/v1/dbstab", Handler_SelectTable)
    e.POST("/api/v1/dbcs", Handler_ConcurrentSelect)

    // Start server
    //e.Logger.Fatal(e.Start(":8000"))
    e.Start(":8000")
}
